/*
 *  Copyright 2004 Blandware (http://www.blandware.com)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License");
 *  you may not use this file except in compliance with the License.
 *  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software
 *  distributed under the License is distributed on an "AS IS" BASIS,
 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *  See the License for the specific language governing permissions and
 *  limitations under the License.
 */
package com.blandware.atleap.webapp.taglib.core.grid;

import com.blandware.atleap.webapp.taglib.core.util.TaglibConstants;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import javax.servlet.jsp.JspException;
import javax.servlet.jsp.JspTagException;
import javax.servlet.jsp.PageContext;
import javax.servlet.jsp.tagext.JspFragment;
import javax.servlet.jsp.tagext.SimpleTagSupport;
import java.io.IOException;

/**
 * <p>This tag iterates over all pages in pager and exports page number on each
 * iteration.
 * <br />
 * This tag is only valid when nested within <em>pager</em> tag.</p>
 * <p>
 * Allowed attributes are:
 * <ul>
 * <li>
 * <b>var</b> - name of variable to which page number will be saved on each
 * iteration. If not specified, this is assigned to
 * <code>TaglibConstants.PAGE_NUMBER_ATTR</code>.
 * </li>
 * </ul>
 * </p>
 * <p><a href="PagesIteratorTag.java.html"><i>View Source</i></a></p>
 *
 * @author Sergey Zubtsovskiy <a href="mailto:sergey.zubtsovskiy@blandware.com">&lt;sergey.zubtsovskiy@blandware.com&gt;</a>
 * @version $Revision: 1.9 $ $Date: 2006/08/03 10:08:20 $
 * @see PagerTag
 * @see PageTag
 * @see CurrentPageTag
 * @jsp.tag name="pagesIterator"
 * body-content="scriptless"
 */
public class PagesIteratorTag extends SimpleTagSupport {

	protected transient final Log log = LogFactory.getLog(PagesIteratorTag.class);

	/**
	 * Page Context attribute name under which number of page must be saved on each iteration
	 */
	protected String var;

	/**
	 * Number of page on each iteration
	 */
	protected Integer pageNumber = new Integer(1);

	private int loopStart = 0;
	private int loopFinish = 0;

	/**
     * Returns name of variable which will accept number of page
     *
	 * @return name of variable
	 * @jsp.attribute required="false"
	 * rtexprvalue="true"
	 * type="java.lang.String"
	 * description="Page Context attribute name under which number of page must be saved on each iteration"
	 */
	public String getVar() {
		return var;
	}

    /**
     * Sets name of variable which will accept number of page
     *
     * @param var name of variable to set
     */
	public void setVar(String var) {
		this.var = var;
	}

    /**
     * Returns current page number
     *
     * @return page number
     */
	public Integer getPageNumber() {
		return pageNumber;
	}

    /**
     * Sets current page number
     *
     * @param pageNumber page number to set
     */
	public void setPageNumber(Integer pageNumber) {
		this.pageNumber = pageNumber;
	}

	/**
	 * Constructs an iterator for collection of page numbers and loops through the body once per element.
	 *
	 * @throws JspTagException     if a JSP exception has occurred
	 * @throws java.io.IOException if there is an error when invoking body content
	 */
	public void doTag() throws JspException, IOException {

		PageContext pageContext = (PageContext) getJspContext();

		// This tag is only valid when nested within 'pager' tag, so check this
		PagerTag parentPagerTag = (PagerTag) findAncestorWithClass(this, PagerTag.class);

		if ( parentPagerTag == null ) {
			JspTagException e = new JspTagException("Parent tag is invalid! This tag is only valid when nested within 'pager' tag");
			throw e;
		}

		GridTag parentGridTag = (GridTag) findAncestorWithClass(this, GridTag.class);

		// Calculate loop start and loop finish
		// loop start - page number to start iteration from
		// loop finish - page number to finish iteration on

		int pageCount = parentPagerTag.getPageCount().intValue();
		int currentPageNumber = parentGridTag.getCurrentPageNumber().intValue();
		int firstPageNumber = 1;
		int lastPageNumber = parentPagerTag.getLastPageNumber().intValue();
		int diff = (pageCount / 2);
		loopStart = currentPageNumber - diff;
		if ( loopStart < firstPageNumber ) {
			loopStart = firstPageNumber;
		}
		loopFinish = loopStart + pageCount - 1;
		if ( loopFinish > lastPageNumber ) {
			loopFinish = lastPageNumber;
			loopStart = loopFinish - pageCount + 1;
			if ( loopStart < firstPageNumber ) {
				loopStart = firstPageNumber;
			}
		}

		if ( var == null ) {
			var = TaglibConstants.PAGE_NUMBER_ATTR;
		}

		while ( loopStart <= loopFinish ) {
			// Export next page number and invoke body content into standard JSP out
			pageNumber = new Integer(loopStart++);
			pageContext.setAttribute(var, pageNumber);
			JspFragment body = getJspBody();
			if ( body != null ) {
				body.invoke(null);
			}
		}
	}

}
